


#$
损失函数
损失函数是前向传播计算出的的y与已知答案y_的差距
神经网络的优化目的就是找到一套参数使得y和y_无限接近
它们的差距loss值最小
均方误差
自定义
交叉熵




#$_________________________________
#获取指定层的特征显示
layer_outputs = [layer.output for layer in model.layers]

activation_model=tf.keras.models.Model(inputs=model.input, outputs = layer_outputs)

pred=activation_model.predict(test_images[1].reshape(1,28,28,1))
print(len(pred))
#pred[1][0,:,:,5])  第2层网络的0:不知道什么::所有行列第5个卷积核的结果
plt.imshow(pred[1][0,:,:,5])#1为第二个过滤器

plt.show()
#$_________________________________
#神经网络堆叠
tf.concat([x1,x2],axis=3)

#$_________________________________
#全连接层
Flatten 把卷积送过来的数据拉直
Dense  全连接
#$_________________________________
卷积-批标准化-激活-池化-舍弃-全链接

#$_________________________________
#舍弃 Dropout
为了缓解神经网络过拟合,在神经网络训练过程中
常把隐藏层的部分神经元按照一定比例从神经网络中
零时舍弃
在使用神经网络时再恢复舍弃的
tf.keras.layers.Dropout(舍弃比例) #0.2为20%舍弃

#$_________________________________
#池化 Pooling
池化操作用于减少卷积神经网络中特征数据量
有最大池化和均值池化
最大池化可以提取图片纹理
均值池化可以保留背景特征
最大池化:
tf.keras.layers.MaxPool2D(
    pool_size=池化核尺寸, #正方形或(w,h)
    strides=池化步长, #整数或(h,w)默认pool_size
    padding="valid" #same  默认valid
    )
均值池化:
tf.keras.layers.AveragePooling2D(
    )

#$_________________________________
#批标准化  BN
tf.keras.layers.BatchNormalization()
标准化:使数据符合0均值,1为标准差的分布
批标准化:对一小批数据(batch),做标准化处理
常用在卷积操作和激活操作之间
卷积之后激活之前

#$_________________________________
#全零填充
为使输入特征图边长和输出特征图边长相等
用全零 padding="SAME"
不使用 padding="VALID"(默认)


#$_________________________________
#感受野
卷积神经网络各输出特征图中的每个像素点,
在原始输入图像上映射区域的大小。



#$_________________________________
#卷积计算
卷积就是特征提取器CBAPD
卷积核按指定步长在图片上滑动,重合区域对应元素求和
再+偏置项得到输出特征的一个像素点,卷积核通道数
和输入特征图通道数一致
当输入特征图边长大于10时,2层3*3卷积核比一层5*5卷积核性能要好
如果卷积后还有BN操作则不激活函数

tf.Keras.layers.Conv2D(
    filters=卷积核个数,
    kernel_size=卷积核尺寸,#(宽,高)宽高相等写一个
    strides=滑动步长,#(w,h)默认相等1
    padding="same"or"valid", #默认valid
    activation="relu",sigmoid,tanh,sortmax 如后面操作有BN此处不写
    input_shape=(宽,高,通道数) #输入特征图维度可省略
    )
    
假设：输入图片（Input）大小为I*I，卷积核（Filter）大小为K*K，步长（stride）为S，填充（Padding）的像素数为P，那卷积层输出（Output）的特征图大小为多少呢?

可以得出推导公式：

O=（I-K+2P）/S+1




#$_________________________________
#返回张量沿指定维度最大值的索引

test = np.array([[1, 2, 3], [2, 3, 4], [5, 4, 3], [8, 7, 2]])
print("test:\n", test)
print("每一列的最大值的索引：", tf.argmax(test, axis=0))  # 返回每一列最大值的索引
print("每一行的最大值的索引", tf.argmax(test, axis=1))  # 返回每一行最大值的索引



#$_________________________________
#assign_sum(要自减的内容)  参数自更新,使用前先tf.Varianle
定义为可训练(可自更新)

x = tf.Variable(4)
x.assign_sub(1)
print("x:", x)  # 4-1=3

#$_________________________________
#tf.nn.softmax(x) 使输出符号概率分布
只有符合概率分布才可以与独热码匹配,变为0到1之间的概率值

x1 = tf.constant([[5.8, 4.0, 1.2, 0.2]])  # 5.8,4.0,1.2,0.2（0）
w1 = tf.constant([[-0.8, -0.34, -1.4],
                  [0.6, 1.3, 0.25],
                  [0.5, 1.45, 0.9],
                  [0.65, 0.7, -1.2]])
b1 = tf.constant([2.52, -3.1, 5.62])
y = tf.matmul(x1, w1) + b1
print("x1.shape:", x1.shape)
print("w1.shape:", w1.shape)
print("b1.shape:", b1.shape)
print("y.shape:", y.shape)
print("y:", y)

#####以下代码可将输出结果y转化为概率值#####
y_dim = tf.squeeze(y)  # 去掉y中纬度1（观察y_dim与 y 效果对比）
y_pro = tf.nn.softmax(y_dim)  # 使y_dim符合概率分布，输出为概率值了
print("y_dim:", y_dim)
print("y_pro:", y_pro)

#请观察打印出的shape



y = tf.constant([1.01, 2.01, -0.66])
y_pro = tf.nn.softmax(y)

print("After softmax, y_pro is:", y_pro)  # y_pro 符合概率分布

print("The sum of y_pro:", tf.reduce_sum(y_pro))  # 通过softmax后，所有概率加起来和为1



#$_________________________________
#在分类时用独热码表示标签
tf.one_hot(待转换数据,depth=几分类)
classes = 3
labels = tf.constant([1, 0, 2])  # 输入的元素值最小为0，最大为2
output = tf.one_hot(labels, depth=classes)
print("result of labels1:", output)
print("\n")


#$_________________________________
#遍历元素组合成索引和元素
#python内建函数
seq = ['one', 'two', 'three']
for i, element in enumerate(seq):
    print(i, element)






#$_________________________________
#某个函数对指定参数的求导运算

with tf.GradientTape() as tape:
    x = tf.Variable(tf.constant(3.0))
    y = tf.pow(x, 2)
grad = tape.gradient(y, x)
print(grad)

#$_________________________________
#把数据和标签配成对。准备喂如神经网络
features = tf.constant([12, 23, 10, 17])
labels = tf.constant([0, 1, 1, 0])
dataset = tf.data.Dataset.from_tensor_slices((features, labels))
for element in dataset:
    print(element)

#$_________________________________
#数学运算
对应元素的四则运算：tf.add,tf.subtract, tf.multiply, tf.divide
平方、次方与开方：tf.square,tf.pow, tf.sqrt
矩阵乘：tf.matmul
例:tf.add(张量1,张量2)    只有维度相同的张量才能运算
#$_________________________________
#常用函数
tf.Variable(初始值)  将变量标记为可训练,被标记的变量会在反向传播时记录梯度信息,
常用该函数标记待训练参数
w=tf.Variable(tf.tandom.normal([2,2],mean=0,stddev=1))


#$_________________________________
#生成正态分布的随机数,默认均值0,标准差1
tf.random.normal(维度,mean=均值,stddev=标准差)
#生成截断式正态分布随机数
tf.random.truncated_normal(维度,mean=均值,stddev=标准差)
保证均值在正负2倍标准差之内

#$_________________________________
#numpy转tensor
a=np.aranfe(0,5)
tf.convert_to_tensor(a,dtype=tf.int64)

#$_________________________________
数据类型
tf.int32,tf.float32,tf.float64
tf.bool (tf.constant([True,False]))
tf.string,  (tf.const("hello"))
#$_________________________________
#张量Tensor,多维数组(列表),阶(张量维数)
创建张量:tf.constant(张量内容,dtype=数据类型(可选))
a=tf.constant([1,5],dtype=tf.int64)
a.dtype,a.shape形状,
tf.zeros(维度)#创建全为0张量
tf.ones(维度)#创建全为1张量
tf.fill(维度,指定值)#创建全为指定值张量


#$_________________________________
线性回归基础
y=mx+b,求解m和b
MAE：最小绝对差(不好)

MSE：最小均方差


#$_________________________________
TF2中使用TF1api需要在使用前声明一次
tf.compat.v1.disable_eager_execution()
导入 
from tensorflow.compat.v1.keras import backend as K


